// package ecdsa密码套件，主要用于账户
package ecdsa

import (
	"crypto/ecdsa"
	"encoding/hex"
	"osiris/config"
	"osiris/logger"
	"osiris/ocrypto/rand"

	"github.com/ethereum/go-ethereum/common"
	ethcrypto "github.com/ethereum/go-ethereum/crypto"
)

// GenerateAccount 生成账户的私钥、地址（公钥可以根据私钥推）、初始随机数
//
//	@return *ecdsa.PrivateKey
//	@return string 地址（取部分公钥切片做 Keccak256Hash得到）
//	@return int64 初始随机数
//	@return error
func GenerateAccount() (*ecdsa.PrivateKey, string, int64, error) {
	nonce, err1 := rand.GenerateNonce(config.MaxAccountNonce)
	if err1 != nil {
		logger.Error(map[string]interface{}{"[ecdsa] [Generate Account Key Pair] Generate Nonce": err1})
		return nil, "", 0, err1
	}

	privKey, err := ethcrypto.GenerateKey()
	if err != nil {
		logger.Error(map[string]interface{}{"[ecdsa] [Generate Account Key Pair] ethcrypto.GenerateKey()": err})
		return nil, "", 0, err
	}

	pubKey := privKey.PublicKey
	address := ethcrypto.PubkeyToAddress(pubKey).Hex()
	return privKey, address, nonce, nil
}

// ECDSAPrivKeyToStr *ecdsa.PrivateKey转字符串
//
//	@param privKey
//	@return string
func ECDSAPrivKeyToStr(privKey *ecdsa.PrivateKey) string {
	return hex.EncodeToString(ethcrypto.FromECDSA(privKey))
}

// StrToECDSAPrivKey 字符串转*ecdsa.PrivateKey
//
//	@param privateKeyStr
//	@return *ecdsa.PrivateKey
//	@return error
func StrToECDSAPrivKey(privateKeyStr string) (*ecdsa.PrivateKey, error) {
	decodedPrivateKey, err1 := hex.DecodeString(privateKeyStr)
	if err1 != nil {
		return nil, err1
	}

	privateKey, err2 := ethcrypto.ToECDSA(decodedPrivateKey)
	if err2 != nil {
		return nil, err2
	}

	return privateKey, nil
}

// AccountAddrToStr 账户地址（common.Address）转字符串
//
//	@param commonAddr
//	@return string
func AccountAddrToStr(commonAddr common.Address) string {
	return commonAddr.Hex()
}

// StrToAccountAddr 字符串转账户地址（common.Address）
//
//	@param str
//	@return common.Address
func StrToAccountAddr(str string) common.Address {
	return common.HexToAddress(str)
}

// AccountAddrToBytes 账户地址（common.Address）转字节数组
//
//	@param commonAddr
//	@return []byte
func AccountAddrToBytes(commonAddr common.Address) []byte {
	return commonAddr.Bytes()
}

// BytesToAccountAddr 字节数组转账户地址（common.Address）
//
//	@param bytes
//	@return common.Address
func BytesToAccountAddr(bytes []byte) common.Address {
	return common.BytesToAddress(bytes)
}

// StrToAccountBytes 账户地址字符串转字节数组
//  @param accountStr 
//  @return []byte 
func StrToAccountBytes(accountStr string) []byte {
	return AccountAddrToBytes(StrToAccountAddr(accountStr))
}

// BytesToAccountStr 账户地址字节数组转字符串
//  @param accountBytes 
//  @return string 
func BytesToAccountStr(accountBytes []byte) string {
	return AccountAddrToStr(BytesToAccountAddr(accountBytes))
}
